package internal

import (
	"gitee.com/wanjimao/dongli-kit/pkg/mongopkg"
	"gitee.com/wanjimao/dongli-kit/pkg/mysqlpkg"
	"gitee.com/wanjimao/dongli-kit/pkg/setting"
	"time"

	"gitee.com/wanjimao/dongli-kit/fxmain/pkg/mfx"
	"gitee.com/wanjimao/dongli-kit/orm/nosql/diface"
	"gitee.com/wanjimao/dongli-kit/orm/pkg/ofx"
	"gitee.com/wanjimao/dongli-kit/server/pkg/sfx"
	"gitee.com/wanjimao/dongli-kit/server/siface"
	"gitee.com/wanjimao/dongli-kit/utility"
	"github.com/redis/go-redis/v9"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/trace"
	"go.uber.org/fx"
	"go.uber.org/zap"

	pb "gitee.com/wanjimao/dongli-platform/api/gen/auth/api"
	"gitee.com/wanjimao/dongli-platform/services/auth/internal/db"
	"gitee.com/wanjimao/dongli-platform/services/auth/pkg/afx"
)

type Service struct {
	utility.WithoutAuth
	logger    *zap.Logger
	jwtSecret string
	url       string
	db        *db.Database
	tracer    trace.Tracer
	redisCli  *redis.Client
	jwtExpire time.Duration
	set       setting.Param
	mysqlDb   mysqlpkg.Param
	mongoDb   mongopkg.Param
}

func (s *Service) RegisterWithGrpcServer(server siface.IGrpcServer) error {
	pb.RegisterAuthServiceServer(server.GrpcServer(), s)
	return nil
}

func NewService(
	l *zap.Logger,
	jwtSecret string,
	url string,
	coll diface.ICollection,
	redisCache diface.ICache,
	appName string,
	tracer trace.Tracer,
	redisCli *redis.Client,
	jwtExpire int32,
	set setting.Param,
	mysqlDb mysqlpkg.Param,
	mongoDb mongopkg.Param,
) (result *Service, err error) {
	result = &Service{
		logger:    l,
		jwtSecret: jwtSecret,
		url:       url,
		db:        db.OpenDatabase(l, appName, coll, redisCache),
		tracer:    tracer,
		redisCli:  redisCli,
		jwtExpire: time.Duration(jwtExpire) * time.Hour,
		mysqlDb:   mysqlDb,
		set:       set,
		mongoDb:   mongoDb,
	}
	return
}

var ServiceModule = fx.Provide(
	func(
		l *zap.Logger,
		sSetting afx.AuthSettingParams,
		aParams mfx.AppParams,
		dbProvider ofx.DocumentStoreParams,
		rcParams ofx.RedisCacheParams,
		redisParams ofx.RedisParams,
		set setting.Param,
		mysqlDb mysqlpkg.Param,
		mongoDb mongopkg.Param,
	) (rpc sfx.GrpcServiceResult, err error) {
		if coll, e := dbProvider.DriverProvider.OpenDbDriver(sSetting.AuthStoreName); e != nil {
			err = e
		} else {
			if svc, e := NewService(
				l,
				sSetting.JwtTokenSecret,
				sSetting.AuthUrl,
				coll,
				rcParams.RedisCache,
				aParams.AppName,
				otel.GetTracerProvider().Tracer(sSetting.AuthStoreName),
				redisParams.Redis,
				sSetting.JwtTokenExpire,
				set,
				mysqlDb,
				mongoDb,
			); e != nil {
				err = e
			} else {
				rpc.GrpcService = svc
			}
		}
		return
	},
)
